# Dungeon view handler

#   Akalabeth Re-Bourne
#   Copyright (C) 2008 Norman B. Lancaster
#
#    This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#   along with this program.  If not, see http://www.gnu.org/licenses/

# Configuration variables
declare -r dvXOfsScreen=0
declare -r dvYOfsScreen=0
declare -r -a dvXOfsL=(0  0  8  14 18)
declare -r -a dvYOfsL=(0  4  7  9  10)
declare -r -a dvXOfsR=(40 34 30 27 27)
declare -r -a dvYOfsR=(0  4  7  9  10)
declare -r -a dvXOfsC=(0  8  14 18 21)
declare -r -a dvYOfsC=(0  4  7  9  10)
declare -r dvImagesPerTile=15
declare -r dvDepths=5

# Renders the dungeon view from the given location and direction
# $1 X location
# $2 Y location
# $3 Direction (N, E, S, W)
function DVRenderDungeon
{
	local pX=0 pY=0 rX=0 rY=0 cX cY tX tY depth i

	# Clear the dungeon view area
	(( i=0 ))
	while (( i < 24 )); do
		ATGoto dvXOfsScreen $(( dvYOfsScreen+i ))
		
		# Floor and ceiling fill, wow!
		if (( i < 10 )); then ATFG 4
		elif (( i >= 14 )); then ATFG 8
		else ATFG 0; fi
		if (( i%2 )); then
			echo -ne "\` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \`\040"
		else
			echo -ne "\040\` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \` \`"
		fi
		(( i++ ))
	done
	
	# Set up render control variables
	case $3 in
		N ) pY=-1; rX=1 ;;
		E ) pX=1; rY=1 ;;
		S ) pY=1; rX=-1 ;;
		W ) pX=-1; rY=-1 ;;
		* )
			echo "EE DVRenderDungeon Invalid direction passed" 1>&2
			exit 1 ;;
	esac
	
	# Start rendering in the back field
	(( cX=$1+(pX*(dvDepths-1)) ))
	(( cY=$2+(pY*(dvDepths-1)) ))
	
	# Projection loop
	(( depth=dvDepths-1 ))
	while (( depth >= 0 )); do
		# Left field
		DVRenderLocation $(( cX+(rX*-1) )) $(( cY+(rY*-1) )) L $depth
		# Right field
		DVRenderLocation $(( cX+rX )) $(( cY+rY )) R $depth
		# Center field
		DVRenderLocation $cX $cY C $depth
		
		# Apply the projection
		(( cX=cX+(pX*-1) ))
		(( cY=cY+(pY*-1) ))
		
		(( depth-- ))
	done
	
	return 0
}

# Called once for each render location during DVRenderDungeon
# $1 Map X
# $2 Map Y
# $3 Orientation (L, R, C)
# $4 Depth
function DVRenderLocation
{
	local tileNum tileGFX objNum objGFX ofsX ofsY oOfs
	
	# Get tile information
	MIGetTile $1 $2
	tileNum=$gReturnValue
	MIGetFlag $tileNum G
	tileGFX=$gReturnValue
	
	# Pull screen offset for the given orientation and depth
	case $3 in
		L ) ofsX=${dvXOfsL[$4]}; ofsY=${dvYOfsL[$4]}; oOfs=0 ;;
		R ) ofsX=${dvXOfsR[$4]}; ofsY=${dvYOfsR[$4]}; oOfs=1 ;;
		C ) ofsX=${dvXOfsC[$4]}; ofsY=${dvYOfsC[$4]}; oOfs=2 ;;
	esac

	# Don't render tiles with a GFX < 0
	if (( tileGFX >= 0 )); then
		ATGoto $(( ofsX+dvXOfsScreen )) $(( ofsY+dvYOfsScreen ))
		echo -ne ${aiImageCache[$(( miMapGFXOfs+((tileGFX*dvImagesPerTile)+(oOfs*dvDepths)+$4) ))]}
	fi
	
	# Only render objects and mobs when they are in the center orientation
	if [[ "$3" == "C" ]]; then
		# Get object information
		OIGetObject $1 $2
		objNum=$gReturnValue
		if (( objNum >= 0 )); then
			OIGetFlag $objNum G
			objGFX=$gReturnValue
			# Don't render objects if thier GFX < 0
			if (( objGFX >= 0 )); then
				ATGoto $(( ofsX+dvXOfsScreen )) $(( ofsY+dvYOfsScreen ))
				echo -ne "${aiImageCache[$(( oiObjGFXOfs+( (objGFX*dvDepths)+$4 ) ))]}"
			fi
		fi
	fi
	
	return 0
}

